#include "GenAgent.h"
#include <QThread>
#include <QDebug>

GenAgent::GenAgent(const TGenConfig& genConfig)
{
	m_genConfig = genConfig;
	// init sumInfo 
	sumInfo.tps = sumInfo.user = 0;
	sumInfo.resp = 0;
}

GenAgent::~GenAgent()
{
}

// sendCommand
void GenAgent::SendCommand(int type)
{
	TPacket packet;
	
	switch(type){
		case RUN_REQ:
			protocol_make_pkt(packet, type, 0, NULL, 0);
			protocol_send_pkt(m_socket, packet);
			break;
		case STOP_REQ:
			protocol_make_pkt(packet, type, 0, NULL, 0);
			protocol_send_pkt(m_socket, packet);
			break;
		default:
			qDebug() << "GenAgent::SendCommand: unknown command type";
			break;
	}
}

void GenAgent::SendProfile(const TProfile& profile)
{
	TPacket packet;
	int type = PROFILE_REQ;
	protocol_make_pkt(packet, type, 0, (uint8_t *)&profile, sizeof(profile));
	protocol_send_pkt(m_socket, packet);
}

// slots
// initialize, run in another thread different from the constructor
void GenAgent::InitAgent()
{
	m_socket = new QTcpSocket();
	QString genIP(m_genConfig.ip.c_str());
	QObject::connect(m_socket, SIGNAL(readyRead()), this, SLOT(readReadyHandle()));
	m_socket->connectToHost(genIP, GenListenPort);

	if(m_socket->waitForConnected(1000)){
		qDebug() << "GenAgent::InitAgent: connected to " << m_genConfig.ip;
	} else {
		qDebug() << m_socket->error();
	}
}

// make sure socket connected
void GenAgent::ConnectGenerator()
{
	if(m_socket->waitForConnected(1000)){
		emit connectCompleted(0);
	} else {
		emit connectCompleted(1);
	}
}

// recv reply
void GenAgent::readReadyHandle()
{
	static char buffer[READ_BUFFER_SIZE];
	int count;
	QList<TSumInfo> sumInfoList;

	if((count = m_socket->read(buffer, READ_BUFFER_SIZE)) < (int)sizeof(TPacketHeader)){
		qDebug() << "GenAgent::readReadyHandle: readReady read count < sizeof(header), count = " << count;
		qDebug() << m_socket->error();
		return;
	}
	TPacket reply;
	TSumInfo difSumInfo;

	// handle the situation where several data pile together
	char *i;
	char *sumInfoIndex;
	int cur = 0;
	for(i = buffer; i < buffer + count; i += sizeof(TPacketHeader)){
		// extract header
		reply.header = *((PPacketHeader)(i));

		// if the packet has extra data
		if(count > (int)sizeof(TPacketHeader)){
			reply.data = (uint8_t *)(i) + sizeof(TPacketHeader);
			reply.length = count - sizeof(TPacketHeader);
		} else { // doesnot contain data except the header
			reply.data = NULL;
			reply.length = 0;
		}
		// get the packet type
		int type = reply.header.head & P_TYPE_MASK;
		switch(type){
			case RUN_REP:
				emit commandCompleted(m_genConfig.ip, protocol_get_status(reply));
				break;
			case STOP_REP:
				emit commandCompleted(m_genConfig.ip, protocol_get_status(reply));
				break;
			case PROFILE_REP:
				emit commandCompleted(m_genConfig.ip, protocol_get_status(reply));
				break;
			case SUM_REP:
				for(cur = 0, sumInfoIndex = reply.data; sumInfoIndex < reply.data + reply.length; cur ++, sumInfoIndex += sizeof(TSumInfo)){
					oldSumInfo = sumInfo;
					sumInfo = *((PSumInfo)(reply.data));
					
					// cal increment, sumInfo should not < 0
					difSumInfo.tps = sumInfo.tps - oldSumInfo.tps;
					difSumInfo.user = sumInfo.user - oldSumInfo.user;
					difSumInfo.resp = sumInfo.resp - oldSumInfo.resp;

					emit dataArrived(m_genConfig.ip, difSumInfo);
				}
				i += sizeof(TSumInfo);
				break;
			default:
				qDebug() << "GenAgent::readReadyHandle: unknown type: " << type;
				break;
		}
	}
}
